#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define SIZE 1024
char pwd[SIZE];
char commandline[SIZE];
char*  argv[64];
char env[SIZE];
int lastcode = 0;
#define SEP " "
const char* UserName()
{
    char * username = getenv("USER");
    if(username) return username;
    else return "None";
}
const char* CurrentWorkDir()
{
    char* dir = getenv("PWD");
    if(dir)  return dir;
    else return "None";
}
const char* HomeName()
{
    char* homename = getenv("HOMENAME");
    if(homename)  return homename;
    else return "None";
}
int interactive(char out[],int size)
{
    printf("[%s@%s %s]$ ",UserName(),HomeName(),CurrentWorkDir());
    //获取用户输入字符串用fgets()函数
    fgets(out,size,stdin);
    out[strlen(out)-1] = 0;
    return strlen(out);
}
void Split(char in[])
{
    int i = 0;
    argv[i++] = strtok(in,SEP);
    while(argv[i++] = strtok(NULL,SEP));
    if(strcmp(argv[0],"ls")==0)
    {
        argv[i-1] = (char* )"--color";
        argv[i] = NULL;
    }
}
void excute()
{

    pid_t id = fork();
    if(id==0)
    {
        //让子进程执行命令
        execvp(argv[0],argv);
        exit(1);
    }
    int status = 0;
    pid_t rid = waitpid(id,&status,0);
    if(rid == id )lastcode  = WEXITSTATUS(status);
}
char* Home()
{
    return getenv("HOME");
}
//处理内建命令
int  BuildinCmd()
{
    //处理内建命令
    int ret = 0;
    //1. 检测是否是内建命令，是 1，否2
    if(strcmp("cd",argv[0])==0)
    {
        //2. 执行
        ret = 1;
        char* target = argv[1];//判断cd xxx 还是cd
        if(!target) target = Home();//获取要进入的目录名
        chdir(target);//改变当前工作目录
        char temp[1024];
        getcwd(temp,1024);
       snprintf(pwd,SIZE,"PWD=%s",temp);//将要进入的目录修改到环境变量
       putenv(pwd);//修改环境变量
    }
    else if(strcmp("export",argv[0])==0)
    {
        ret = 1;
        if(argv[1])
        {
            strcpy(env,argv[1]);
            putenv(env);
        }
    }
    else if(strcmp("echo",argv[0])==0)
    {
        ret = 1;
        if(argv[1]==NULL)
        {
            printf("\n");
        }
        else{
            if(argv[1][0]=='$')
            {
                if(argv[1][1] == '?')
                {
                    printf("%d\n",lastcode);
                    lastcode = 0; 
                }
                else{
                    char* e = getenv(argv[1]+1);
                    if(e)
                    printf("%s\n",e);
                }
            }
            else{
                printf("%s\n",argv[1]);
            }
        }
    }
    return ret;
}
int main()
{
    while(1)
    {
         //1. 打印命令行提示符，获取用户输入的命令字符串
         int ret = interactive(commandline,SIZE);
         if(ret == 0) continue;
         //2. 分割字符串使用strtok()函数分割
         Split(commandline);
         //3. 处理内建命令
         BuildinCmd(); 
         //3. 执行这个命令使用fork()函数创建子进程执行命令
         excute();
    }
    return 0;

}
